/*
    Flood is a program to test the cut method on soft constraints problems
    Copyright (C) 2011  Mattia Gamba

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef GENERATOR_H
#define GENERATOR_H

#include <QMap>
#include <QPair>
#include <QVector>
#include <QTime>
#include <math.h>
#include <QApplication>

class Parameters{
public:
    Parameters(){}
    Parameters(int,int,int,int,float);
    int getN() const{return n;}
    int getM() const{return m;}
    int getSt() const{return st;}
    int getSc() const{return sc;}
    float getMaxV() const{return maxV;}
    int getMaxConstraints() const{return maxConstraints;}
private:

    //Number of variables
    int n;
    //Size of the variable's domain
    int m;
    //Density
    int st;
    //Tightness
    int sc;
    //Max value for the constraints
    float maxV;
    //Pam used to maintain the desired graph density
    int maxConstraints;
};

class Link{
public:
    Link(){}
    //Map that holds only constraints relative to the parent link
    QMap<QPair<int,int>,int> constraint_table;
    //Useful container for cut purpose
    QMap<int, uint> floats;
    ~Link(){
        this->constraint_table.clear();
    }
};

class Variable{
public:
    Variable(){}
    Variable(int i, QMap<int,int> v):id(i){vals = v;}
    ~Variable(){
        vals.clear();
    }
    int id;
    //Map that holds values for the variable's constraints
    QMap<int,int> vals;
    QMap<int,uint> floats;

};


class Problem{
public:
    Problem(){}
    Problem(const Problem& pr): constraints(pr.constraints),variables(pr.variables), _pam(pr._pam){}
    QMap<QPair<int,int>,Link> getLinksFor(int);
    void setParameters(Parameters p){_pam = p;}
    QMap<QPair<int,int>,Link> constraints;
    //Vector that holds the variables ordered by id
    QVector<Variable> variables;
    void addVar(Variable v);
    Problem * getCutHard(int);
    Parameters _pam;
    ~Problem();

};

class Generator{
public:
    Generator(){curr_density = 0;curr_tightness = 0;}
    Problem * generate();
    void setParameters(Parameters pam);
    Parameters getParameters() const;

private:
    Parameters pam;
    float curr_density;
    float curr_tightness;
};

#endif // GENERATOR_H
